package nl.tudelft.jpacman.level;

import nl.tudelft.jpacman.npc.Ghost;
import nl.tudelft.jpacman.points.DefaultPointCalculator;
import nl.tudelft.jpacman.points.PointCalculator;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;

class PlayerCollisionsTest {
    private PointCalculator pointCalculator;
    private PlayerCollisions playerCollisions;

    /**
     * init
     */
    @BeforeEach
    public void setup() {
        pointCalculator = new DefaultPointCalculator();
        playerCollisions = new PlayerCollisions(pointCalculator);
    }

    /**
     * 规则1：player to ghost
     */
    @Test
    @Order(1)
    void player_Ghost() {
        Player player = mock(Player.class);
        Ghost ghost = mock(Ghost.class);
        playerCollisions.collide(player, ghost);
        Mockito.verify(player, times(1)).setAlive(false);
        Mockito.verify(player, times(1)).setKiller(ghost);
    }

    /**
     * 规则2：player to pellet
     */
    @Test
    @Order(2)
    void player_Pellet() {
        Player player = mock(Player.class);
        Pellet pellet = mock(Pellet.class);
        playerCollisions.collide(player, pellet);
        Mockito.verify(pellet, times(1)).leaveSquare();
    }

    /**
     * 规则3：ghost to player
     */
    @Test
    @Order(3)
    void ghost_Player() {
        Ghost ghost = mock(Ghost.class);
        Player player = mock(Player.class);
        playerCollisions.collide(ghost, player);
        Mockito.verify(player, times(1)).setAlive(false);
        Mockito.verify(player, times(1)).setKiller(ghost);
    }

    /**
     * ghost to pellet
     */
    @Test
    @Order(4)
    void ghost_Pellet() {
        Ghost ghost = mock(Ghost.class);
        Pellet pellet = mock(Pellet.class);
        playerCollisions.collide(ghost, pellet);
        Mockito.verify(pellet, times(0)).leaveSquare();
    }

    /**
     * pellet to player
     */
    @Test
    @Order(5)
    void pelletCollidePlayer() {
        Pellet pellet = mock(Pellet.class);
        Player player = mock(Player.class);
        playerCollisions.collide(pellet, player);
        Mockito.verify(pellet, times(1)).leaveSquare();
    }

    /**
     * pellet to ghost
     */
    @Test
    @Order(6)
    void pelletCollideGhost() {
        Ghost ghost = mock(Ghost.class);
        Pellet pellet = mock(Pellet.class);
        playerCollisions.collide(pellet, ghost);
        Mockito.verify(pellet, times(0)).leaveSquare();
    }

}

